package com.google.srclib.data;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlRootElement;

import com.google.srclib.dataset.StockRecordDataset;

/**
 * 
 * @author YLiang
 * 
 */
@XmlRootElement(name = "InvDataset")
@XmlType(name = "InvDatasetType")
public class InvDataset implements IStockDataset {
	private Date[] date;
	private double[] open;
	private double[] close;
	private double[] high;
	private double[] low;
	private double[] volume;
	private StockDataType chartType;

	public InvDataset() {
		super();
	}

	public InvDataset(StockDataType chartType) {
		super();
		this.chartType = chartType;
	}

	public InvDataset(StockRecordDataset srdata, StockDataType chartType) {
		this(chartType);
	}

	public InvDataset(Date[] date, double[] open, double[] close,
			double[] high, double[] low, double[] volume) {
		super();
		this.date = date;
		this.open = open;
		this.close = close;
		this.high = high;
		this.low = low;
		this.volume = volume;
		this.chartType = StockDataType.DAILY;
	}

	public InvDataset(Date[] date, double[] open, double[] close,
			double[] high, double[] low, double[] volume,
			StockDataType chartType) {
		this(date, open, close, high, low, volume);
		this.chartType = chartType;
	}

	public Date[] getDate() {
		return date;
	}

	public void setDate(Date[] date) {
		this.date = date;
	}

	public double[] getOpen() {
		return open;
	}

	public void setOpen(double[] open) {
		this.open = open;
	}

	public double[] getClose() {
		return close;
	}

	public void setClose(double[] close) {
		this.close = close;
	}

	public double[] getHigh() {
		return high;
	}

	public void setHigh(double[] high) {
		this.high = high;
	}

	public double[] getLow() {
		return low;
	}

	public void setLow(double[] low) {
		this.low = low;
	}

	public double[] getVolume() {
		return volume;
	}

	public void setVolume(double[] volume) {
		this.volume = volume;
	}

	public StockDataType getChartType() {
		return chartType;
	}

	public void setChartType(StockDataType chartType) {
		this.chartType = chartType;
	}

	@SuppressWarnings("deprecation")
	public InvDataset getWeekChartDataset() {
		InvDataset weekChart = new InvDataset(StockDataType.WEEK);
		List<Date> dateList = new ArrayList<Date>();
		List<Double> openList = new ArrayList<Double>();
		List<Double> closeList = new ArrayList<Double>();
		List<Double> highList = new ArrayList<Double>();
		List<Double> lowList = new ArrayList<Double>();
		List<Double> volumeList = new ArrayList<Double>();
		boolean newWeek = true;
		int previousDayofWeek = 0;
		int dayofWeek = 0;
		double openprice = 0;
		double closeprice = 0;
		double highprice = 0;
		double lowprice = Double.MAX_VALUE;
		double volumeofweek = 0;
		for (int i = 0; i < date.length; i++) {
			Date day = date[i];
			dayofWeek = day.getDay();
			if (dayofWeek < previousDayofWeek) {
				openList.add(openprice);
				closeList.add(closeprice);
				highList.add(highprice);
				lowList.add(lowprice);
				volumeList.add(volumeofweek);
				newWeek = true;
				openprice = 0;
				closeprice = 0;
				highprice = 0;
				lowprice = Double.MAX_VALUE;
				volumeofweek = 0;
			}
			previousDayofWeek = dayofWeek;
			if (newWeek) {
				dateList.add(day);
				newWeek = false;
				openprice = open[i];
			}
			closeprice = close[i];
			highprice = (highprice > high[i]) ? highprice : high[i];
			lowprice = (lowprice < low[i]) ? lowprice : low[i];
			volumeofweek += volume[i];

			if (i == date.length - 1) {
				openList.add(openprice);
				closeList.add(closeprice);
				highList.add(highprice);
				lowList.add(lowprice);
				volumeList.add(volumeofweek);
			}
		}

		Object[] array = dateList.toArray();
		Date[] dateArray = new Date[array.length];
		for (int i = 0; i < array.length; i++) {
			dateArray[i] = (Date) array[i];
		}
		weekChart.setDate(dateArray);

		array = openList.toArray();
		double[] openArray = new double[array.length];
		for (int i = 0; i < array.length; i++) {
			openArray[i] = (Double) array[i];
		}
		weekChart.setOpen(openArray);

		array = closeList.toArray();
		double[] closeArray = new double[array.length];
		for (int i = 0; i < array.length; i++) {
			closeArray[i] = (Double) array[i];
		}
		weekChart.setClose(closeArray);

		array = highList.toArray();
		double[] highArray = new double[array.length];
		for (int i = 0; i < array.length; i++) {
			highArray[i] = (Double) array[i];
		}
		weekChart.setHigh(highArray);

		array = lowList.toArray();
		double[] lowArray = new double[array.length];
		for (int i = 0; i < array.length; i++) {
			lowArray[i] = (Double) array[i];
		}
		weekChart.setLow(lowArray);

		array = volumeList.toArray();
		double[] volumeArray = new double[array.length];
		for (int i = 0; i < array.length; i++) {
			volumeArray[i] = (Double) array[i];
		}
		weekChart.setVolume(volumeArray);

		return weekChart;
	}

	@SuppressWarnings("deprecation")
	public InvDataset getMonthChartDataset() {
		InvDataset monthChart = new InvDataset(StockDataType.MONTH);

		List<Date> dateList = new ArrayList<Date>();
		List<Double> openList = new ArrayList<Double>();
		List<Double> closeList = new ArrayList<Double>();
		List<Double> highList = new ArrayList<Double>();
		List<Double> lowList = new ArrayList<Double>();
		List<Double> volumeList = new ArrayList<Double>();
		boolean newMonth = true;
		int previousDayofMonth = 0;
		int dayofMonth = 0;
		double openprice = 0;
		double closeprice = 0;
		double highprice = 0;
		double lowprice = Double.MAX_VALUE;
		double volumeofweek = 0;
		for (int i = 0; i < date.length; i++) {
			Date day = date[i];
			dayofMonth = day.getMonth();
			if (i == 0) {
				previousDayofMonth = dayofMonth;
			}
			if (dayofMonth != previousDayofMonth) {
				openList.add(openprice);
				closeList.add(closeprice);
				highList.add(highprice);
				lowList.add(lowprice);
				volumeList.add(volumeofweek);
				newMonth = true;
				openprice = 0;
				closeprice = 0;
				highprice = 0;
				lowprice = Double.MAX_VALUE;
				volumeofweek = 0;
			}
			previousDayofMonth = dayofMonth;
			if (newMonth) {
				dateList.add(day);
				newMonth = false;
				openprice = open[i];
			}
			closeprice = close[i];
			highprice = (highprice > high[i]) ? highprice : high[i];
			lowprice = (lowprice < low[i]) ? lowprice : low[i];
			volumeofweek += volume[i];

			if (i == date.length - 1) {
				openList.add(openprice);
				closeList.add(closeprice);
				highList.add(highprice);
				lowList.add(lowprice);
				volumeList.add(volumeofweek);
			}
		}

		Object[] array = dateList.toArray();
		Date[] dateArray = new Date[array.length];
		for (int i = 0; i < array.length; i++) {
			dateArray[i] = (Date) array[i];
		}
		monthChart.setDate(dateArray);

		array = openList.toArray();
		double[] openArray = new double[array.length];
		for (int i = 0; i < array.length; i++) {
			openArray[i] = (Double) array[i];
		}
		monthChart.setOpen(openArray);

		array = closeList.toArray();
		double[] closeArray = new double[array.length];
		for (int i = 0; i < array.length; i++) {
			closeArray[i] = (Double) array[i];
		}
		monthChart.setClose(closeArray);

		array = highList.toArray();
		double[] highArray = new double[array.length];
		for (int i = 0; i < array.length; i++) {
			highArray[i] = (Double) array[i];
		}
		monthChart.setHigh(highArray);

		array = lowList.toArray();
		double[] lowArray = new double[array.length];
		for (int i = 0; i < array.length; i++) {
			lowArray[i] = (Double) array[i];
		}
		monthChart.setLow(lowArray);

		array = volumeList.toArray();
		double[] volumeArray = new double[array.length];
		for (int i = 0; i < array.length; i++) {
			volumeArray[i] = (Double) array[i];
		}
		monthChart.setVolume(volumeArray);

		return monthChart;
	}
}
